/*
 * TreeProView.java
 */

package treepro;

import calcsdk.nw.ITreePro;
import calcsdk.nw.Patch;
import java.awt.Color;
import java.awt.Dimension;
import java.util.List;
import org.jdesktop.application.Action;
import org.jdesktop.application.ResourceMap;
import org.jdesktop.application.SingleFrameApplication;
import org.jdesktop.application.FrameView;
import org.jdesktop.application.TaskMonitor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.Iterator;
import javax.swing.Timer;
import javax.swing.Icon;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;

/**
 * The application's main frame.
 */
public class TreeProView extends FrameView implements ITreePro {
    
    
    private RefreshTask refreshTask;

    public TreePanel treePanel = null;
    
    
    public void resetCommand() {
        addNodeBtn.setSelected(false);
        addLinkBtn.setSelected(false);
    }
    
    public JScrollPane treeScrollPane = null;
    
    public TaskMonitor taskMonitor;
    
    
    public TreeProView(SingleFrameApplication app) {
        super(app);
        
        TreeProApp.main = this;
        initComponents();

        if (TreeProApp.resultFrame==null) {
            TreeProApp.resultFrame = new ResultFrame();
        }


        treePanel = new TreePanel(this);
      
        //tp.setSize(3000, 3000);
        
        treeScrollPane = new JScrollPane();
        treeScrollPane.add(treePanel);
        treeScrollPane.setViewportView(treePanel);
        jPanel2.add(treeScrollPane);
        //jScrollPane1.setViewportView(treePanel);         
        treePanel.setScreenSize(new Dimension(1024, 768));
        treeScrollPane.getVerticalScrollBar().setUnitIncrement(16);
     
        
        
        actionMap.get("delete_object").setEnabled(false);
        actionMap.get("object_properties").setEnabled(false);            
        
        actionMap.get("link_orient").setEnabled(false);            
        actionMap.get("link_select").setEnabled(false);
        actionMap.get("start_calc").setEnabled(true);
        actionMap.get("stop_calc").setEnabled(false);
        //actionMap.get("delete_links").setEnabled(false);
        
        // status bar initialization - message timeout, idle icon and busy animation, etc
        ResourceMap resourceMap = getResourceMap();
        int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");
        messageTimer = new Timer(messageTimeout, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                statusMessageLabel.setText("");
            }
        });
        messageTimer.setRepeats(false);
        int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");
        for (int i = 0; i < busyIcons.length; i++) {
            busyIcons[i] = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");
        }
        busyIconTimer = new Timer(busyAnimationRate, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                busyIconIndex = (busyIconIndex + 1) % busyIcons.length;
                statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);
            }
        });
        idleIcon = resourceMap.getIcon("StatusBar.idleIcon");
        statusAnimationLabel.setIcon(idleIcon);
        progressBar.setVisible(false);

        // connecting action tasks to status bar via TaskMonitor
        taskMonitor = new TaskMonitor(getApplication().getContext());
        taskMonitor.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
            public void propertyChange(java.beans.PropertyChangeEvent evt) {
                String propertyName = evt.getPropertyName();
                if ("started".equals(propertyName)) {
                    if (!busyIconTimer.isRunning()) {
                        statusAnimationLabel.setIcon(busyIcons[0]);
                        busyIconIndex = 0;
                        busyIconTimer.start();
                    }
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(true);
                } else if ("done".equals(propertyName)) {
                    busyIconTimer.stop();
                    statusAnimationLabel.setIcon(idleIcon);
                    progressBar.setVisible(false);
                    progressBar.setValue(0);
                } else if ("message".equals(propertyName)) {
                    String text = (String)(evt.getNewValue());
                    statusMessageLabel.setText((text == null) ? "" : text);
                    messageTimer.restart();
                } else if ("progress".equals(propertyName)) {
                    int value = (Integer)(evt.getNewValue());
                    progressBar.setVisible(true);
                    progressBar.setIndeterminate(false);
                    progressBar.setValue(value);
                }
            }
        });
        
    }

    @Action
    public void showAboutBox() {
        if (aboutBox == null) {
            JFrame mainFrame = TreeProApp.getApplication().getMainFrame();
            aboutBox = new TreeProAboutBox(mainFrame);
            aboutBox.setLocationRelativeTo(mainFrame);
        }
        TreeProApp.getApplication().show(aboutBox);
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        mainPanel = new javax.swing.JPanel();
        jPanel1 = new javax.swing.JPanel();
        jToolBar2 = new javax.swing.JToolBar();
        jButton1 = new javax.swing.JButton();
        jButton7 = new javax.swing.JButton();
        jSeparator7 = new javax.swing.JToolBar.Separator();
        jButton8 = new javax.swing.JButton();
        jButton12 = new javax.swing.JButton();
        jButton9 = new javax.swing.JButton();
        jSeparator11 = new javax.swing.JToolBar.Separator();
        jButton4 = new javax.swing.JButton();
        jSeparator5 = new javax.swing.JToolBar.Separator();
        jButton17 = new javax.swing.JButton();
        jButton14 = new javax.swing.JButton();
        jButton13 = new javax.swing.JButton();
        jSeparator14 = new javax.swing.JToolBar.Separator();
        labPathCnt = new javax.swing.JLabel();
        labCurrPath = new javax.swing.JLabel();
        jSeparator4 = new javax.swing.JToolBar.Separator();
        labelTime = new javax.swing.JLabel();
        jTabbedPane1 = new javax.swing.JTabbedPane();
        jPanel2 = new javax.swing.JPanel();
        jToolBar1 = new javax.swing.JToolBar();
        addNodeBtn = new javax.swing.JToggleButton();
        addLinkBtn = new javax.swing.JToggleButton();
        jButton10 = new javax.swing.JButton();
        jSeparator9 = new javax.swing.JToolBar.Separator();
        jButton2 = new javax.swing.JButton();
        jButton3 = new javax.swing.JButton();
        jButton5 = new javax.swing.JButton();
        jButton18 = new javax.swing.JButton();
        jSeparator8 = new javax.swing.JToolBar.Separator();
        jButton16 = new javax.swing.JButton();
        jPanel3 = new javax.swing.JPanel();
        tableScrollPane = new javax.swing.JScrollPane();
        nodesTable = new javax.swing.JTable();
        jToolBar3 = new javax.swing.JToolBar();
        jButton11 = new javax.swing.JButton();
        jButton6 = new javax.swing.JButton();
        menuBar = new javax.swing.JMenuBar();
        javax.swing.JMenu fileMenu = new javax.swing.JMenu();
        jMenuItem1 = new javax.swing.JMenuItem();
        jMenuItem2 = new javax.swing.JMenuItem();
        jSeparator1 = new javax.swing.JPopupMenu.Separator();
        jMenuItem3 = new javax.swing.JMenuItem();
        jSeparator2 = new javax.swing.JPopupMenu.Separator();
        javax.swing.JMenuItem exitMenuItem = new javax.swing.JMenuItem();
        jMenu1 = new javax.swing.JMenu();
        jMenuItem15 = new javax.swing.JMenuItem();
        jMenuItem5 = new javax.swing.JMenuItem();
        jMenuItem16 = new javax.swing.JMenuItem();
        jSeparator13 = new javax.swing.JPopupMenu.Separator();
        jMenuItem4 = new javax.swing.JMenuItem();
        jSeparator3 = new javax.swing.JPopupMenu.Separator();
        jMenuItem12 = new javax.swing.JMenuItem();
        jMenuItem13 = new javax.swing.JMenuItem();
        jSeparator6 = new javax.swing.JPopupMenu.Separator();
        jMenuItem6 = new javax.swing.JMenuItem();
        jMenu2 = new javax.swing.JMenu();
        jMenuItem7 = new javax.swing.JMenuItem();
        jSeparator10 = new javax.swing.JPopupMenu.Separator();
        jMenuItem8 = new javax.swing.JMenuItem();
        jMenuItem9 = new javax.swing.JMenuItem();
        jMenuItem10 = new javax.swing.JMenuItem();
        jMenuItem11 = new javax.swing.JMenuItem();
        jSeparator12 = new javax.swing.JPopupMenu.Separator();
        jMenuItem17 = new javax.swing.JMenuItem();
        jMenuItem14 = new javax.swing.JMenuItem();
        javax.swing.JMenu helpMenu = new javax.swing.JMenu();
        javax.swing.JMenuItem aboutMenuItem = new javax.swing.JMenuItem();
        statusPanel = new javax.swing.JPanel();
        javax.swing.JSeparator statusPanelSeparator = new javax.swing.JSeparator();
        statusMessageLabel = new javax.swing.JLabel();
        statusAnimationLabel = new javax.swing.JLabel();
        progressBar = new javax.swing.JProgressBar();

        mainPanel.setName("mainPanel"); // NOI18N
        mainPanel.setLayout(new java.awt.BorderLayout());

        jPanel1.setName("jPanel1"); // NOI18N
        jPanel1.setLayout(new java.awt.BorderLayout());

        jToolBar2.setRollover(true);
        jToolBar2.setName("jToolBar2"); // NOI18N

        javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(treepro.TreeProApp.class).getContext().getActionMap(TreeProView.class, this);
        jButton1.setAction(actionMap.get("file_new")); // NOI18N
        org.jdesktop.application.ResourceMap resourceMap = org.jdesktop.application.Application.getInstance(treepro.TreeProApp.class).getContext().getResourceMap(TreeProView.class);
        jButton1.setText(resourceMap.getString("jButton1.text")); // NOI18N
        jButton1.setFocusable(false);
        jButton1.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton1.setName("jButton1"); // NOI18N
        jButton1.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(jButton1);

        jButton7.setAction(actionMap.get("file_open")); // NOI18N
        jButton7.setText(resourceMap.getString("jButton7.text")); // NOI18N
        jButton7.setFocusable(false);
        jButton7.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton7.setName("jButton7"); // NOI18N
        jButton7.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(jButton7);

        jSeparator7.setName("jSeparator7"); // NOI18N
        jToolBar2.add(jSeparator7);

        jButton8.setAction(actionMap.get("file_save")); // NOI18N
        jButton8.setText(resourceMap.getString("jButton8.text")); // NOI18N
        jButton8.setFocusable(false);
        jButton8.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton8.setName("jButton8"); // NOI18N
        jButton8.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(jButton8);

        jButton12.setAction(actionMap.get("print_table_panel")); // NOI18N
        jButton12.setText(resourceMap.getString("jButton12.text")); // NOI18N
        jButton12.setFocusable(false);
        jButton12.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton12.setName("jButton12"); // NOI18N
        jButton12.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(jButton12);

        jButton9.setAction(actionMap.get("save_image")); // NOI18N
        jButton9.setText(resourceMap.getString("jButton9.text")); // NOI18N
        jButton9.setFocusable(false);
        jButton9.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton9.setName("jButton9"); // NOI18N
        jButton9.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(jButton9);

        jSeparator11.setName("jSeparator11"); // NOI18N
        jToolBar2.add(jSeparator11);

        jButton4.setAction(actionMap.get("set_size")); // NOI18N
        jButton4.setText(resourceMap.getString("jButton4.text")); // NOI18N
        jButton4.setFocusable(false);
        jButton4.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton4.setName("jButton4"); // NOI18N
        jButton4.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(jButton4);

        jSeparator5.setName("jSeparator5"); // NOI18N
        jToolBar2.add(jSeparator5);

        jButton17.setAction(actionMap.get("start_calc")); // NOI18N
        jButton17.setText(resourceMap.getString("jButton17.text")); // NOI18N
        jButton17.setFocusable(false);
        jButton17.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton17.setName("jButton17"); // NOI18N
        jButton17.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(jButton17);

        jButton14.setAction(actionMap.get("stop_calc")); // NOI18N
        jButton14.setText(resourceMap.getString("jButton14.text")); // NOI18N
        jButton14.setFocusable(false);
        jButton14.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton14.setName("jButton14"); // NOI18N
        jButton14.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(jButton14);

        jButton13.setAction(actionMap.get("view_result")); // NOI18N
        jButton13.setText(resourceMap.getString("jButton13.text")); // NOI18N
        jButton13.setFocusable(false);
        jButton13.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton13.setName("jButton13"); // NOI18N
        jButton13.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar2.add(jButton13);

        jSeparator14.setName("jSeparator14"); // NOI18N
        jToolBar2.add(jSeparator14);

        labPathCnt.setFont(resourceMap.getFont("labPathCnt.font")); // NOI18N
        labPathCnt.setForeground(resourceMap.getColor("labPathCnt.foreground")); // NOI18N
        labPathCnt.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        labPathCnt.setText(resourceMap.getString("labPathCnt.text")); // NOI18N
        labPathCnt.setToolTipText(resourceMap.getString("labPathCnt.toolTipText")); // NOI18N
        labPathCnt.setMaximumSize(new java.awt.Dimension(100, 33));
        labPathCnt.setMinimumSize(new java.awt.Dimension(100, 33));
        labPathCnt.setName("labPathCnt"); // NOI18N
        labPathCnt.setPreferredSize(new java.awt.Dimension(33, 33));
        jToolBar2.add(labPathCnt);

        labCurrPath.setFont(resourceMap.getFont("labCurrPath.font")); // NOI18N
        labCurrPath.setForeground(resourceMap.getColor("labCurrPath.foreground")); // NOI18N
        labCurrPath.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
        labCurrPath.setText(resourceMap.getString("labCurrPath.text")); // NOI18N
        labCurrPath.setToolTipText(resourceMap.getString("labCurrPath.toolTipText")); // NOI18N
        labCurrPath.setName("labCurrPath"); // NOI18N
        jToolBar2.add(labCurrPath);

        jSeparator4.setName("jSeparator4"); // NOI18N
        jToolBar2.add(jSeparator4);

        labelTime.setFont(resourceMap.getFont("labelTime.font")); // NOI18N
        labelTime.setText(resourceMap.getString("labelTime.text")); // NOI18N
        labelTime.setToolTipText(resourceMap.getString("labelTime.toolTipText")); // NOI18N
        labelTime.setName("labelTime"); // NOI18N
        jToolBar2.add(labelTime);

        jPanel1.add(jToolBar2, java.awt.BorderLayout.PAGE_START);

        mainPanel.add(jPanel1, java.awt.BorderLayout.PAGE_START);

        jTabbedPane1.setName("jTabbedPane1"); // NOI18N

        jPanel2.setName("jPanel2"); // NOI18N
        jPanel2.setLayout(new java.awt.BorderLayout());

        jToolBar1.setOrientation(1);
        jToolBar1.setRollover(true);
        jToolBar1.setName("jToolBar1"); // NOI18N

        addNodeBtn.setAction(actionMap.get("new_node")); // NOI18N
        addNodeBtn.setText(resourceMap.getString("addNodeBtn.text")); // NOI18N
        addNodeBtn.setFocusable(false);
        addNodeBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        addNodeBtn.setName("addNodeBtn"); // NOI18N
        addNodeBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(addNodeBtn);

        addLinkBtn.setAction(actionMap.get("add_link")); // NOI18N
        addLinkBtn.setText(resourceMap.getString("addLinkBtn.text")); // NOI18N
        addLinkBtn.setFocusable(false);
        addLinkBtn.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        addLinkBtn.setName("addLinkBtn"); // NOI18N
        addLinkBtn.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(addLinkBtn);

        jButton10.setAction(actionMap.get("delete_object")); // NOI18N
        jButton10.setText(resourceMap.getString("jButton10.text")); // NOI18N
        jButton10.setFocusable(false);
        jButton10.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton10.setName("jButton10"); // NOI18N
        jButton10.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(jButton10);

        jSeparator9.setName("jSeparator9"); // NOI18N
        jToolBar1.add(jSeparator9);

        jButton2.setAction(actionMap.get("link_orient")); // NOI18N
        jButton2.setText(resourceMap.getString("jButton2.text")); // NOI18N
        jButton2.setFocusable(false);
        jButton2.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton2.setName("jButton2"); // NOI18N
        jButton2.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(jButton2);

        jButton3.setAction(actionMap.get("link_select")); // NOI18N
        jButton3.setText(resourceMap.getString("jButton3.text")); // NOI18N
        jButton3.setFocusable(false);
        jButton3.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton3.setName("jButton3"); // NOI18N
        jButton3.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(jButton3);

        jButton5.setAction(actionMap.get("delete_links")); // NOI18N
        jButton5.setText(resourceMap.getString("jButton5.text")); // NOI18N
        jButton5.setFocusable(false);
        jButton5.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton5.setName("jButton5"); // NOI18N
        jButton5.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(jButton5);

        jButton18.setAction(actionMap.get("link_allConvert")); // NOI18N
        jButton18.setText(resourceMap.getString("jButton18.text")); // NOI18N
        jButton18.setFocusable(false);
        jButton18.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton18.setName("jButton18"); // NOI18N
        jButton18.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(jButton18);

        jSeparator8.setName("jSeparator8"); // NOI18N
        jToolBar1.add(jSeparator8);

        jButton16.setAction(actionMap.get("object_properties")); // NOI18N
        jButton16.setText(resourceMap.getString("jButton16.text")); // NOI18N
        jButton16.setFocusable(false);
        jButton16.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton16.setName("jButton16"); // NOI18N
        jButton16.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar1.add(jButton16);

        jPanel2.add(jToolBar1, java.awt.BorderLayout.LINE_START);

        jTabbedPane1.addTab(resourceMap.getString("jPanel2.TabConstraints.tabTitle"), jPanel2); // NOI18N

        jPanel3.setName("jPanel3"); // NOI18N
        jPanel3.setLayout(new java.awt.BorderLayout());

        tableScrollPane.setName("tableScrollPane"); // NOI18N

        nodesTable.setModel(new javax.swing.table.DefaultTableModel(
            new Object [][] {

            },
            new String [] {

            }
        ));
        nodesTable.setAutoResizeMode(javax.swing.JTable.AUTO_RESIZE_OFF);
        nodesTable.setCellSelectionEnabled(true);
        nodesTable.setName("nodesTable"); // NOI18N
        nodesTable.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
        nodesTable.getTableHeader().setReorderingAllowed(false);
        tableScrollPane.setViewportView(nodesTable);

        jPanel3.add(tableScrollPane, java.awt.BorderLayout.CENTER);

        jToolBar3.setOrientation(1);
        jToolBar3.setRollover(true);
        jToolBar3.setName("jToolBar3"); // NOI18N

        jButton11.setAction(actionMap.get("resize_table")); // NOI18N
        jButton11.setText(resourceMap.getString("jButton11.text")); // NOI18N
        jButton11.setFocusable(false);
        jButton11.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton11.setName("jButton11"); // NOI18N
        jButton11.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar3.add(jButton11);

        jButton6.setAction(actionMap.get("create_table")); // NOI18N
        jButton6.setText(resourceMap.getString("jButton6.text")); // NOI18N
        jButton6.setFocusable(false);
        jButton6.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
        jButton6.setName("jButton6"); // NOI18N
        jButton6.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
        jToolBar3.add(jButton6);

        jPanel3.add(jToolBar3, java.awt.BorderLayout.LINE_START);

        jTabbedPane1.addTab(resourceMap.getString("jPanel3.TabConstraints.tabTitle"), jPanel3); // NOI18N

        mainPanel.add(jTabbedPane1, java.awt.BorderLayout.CENTER);

        menuBar.setName("menuBar"); // NOI18N

        fileMenu.setText(resourceMap.getString("fileMenu.text")); // NOI18N
        fileMenu.setName("fileMenu"); // NOI18N

        jMenuItem1.setAction(actionMap.get("file_new")); // NOI18N
        jMenuItem1.setName("jMenuItem1"); // NOI18N
        fileMenu.add(jMenuItem1);

        jMenuItem2.setAction(actionMap.get("file_open")); // NOI18N
        jMenuItem2.setName("jMenuItem2"); // NOI18N
        fileMenu.add(jMenuItem2);

        jSeparator1.setName("jSeparator1"); // NOI18N
        fileMenu.add(jSeparator1);

        jMenuItem3.setAction(actionMap.get("file_save")); // NOI18N
        jMenuItem3.setName("jMenuItem3"); // NOI18N
        fileMenu.add(jMenuItem3);

        jSeparator2.setName("jSeparator2"); // NOI18N
        fileMenu.add(jSeparator2);

        exitMenuItem.setAction(actionMap.get("quit")); // NOI18N
        exitMenuItem.setName("exitMenuItem"); // NOI18N
        fileMenu.add(exitMenuItem);

        menuBar.add(fileMenu);

        jMenu1.setText(resourceMap.getString("jMenu1.text")); // NOI18N
        jMenu1.setName("jMenu1"); // NOI18N

        jMenuItem15.setAction(actionMap.get("start_calc")); // NOI18N
        jMenuItem15.setName("jMenuItem15"); // NOI18N
        jMenu1.add(jMenuItem15);

        jMenuItem5.setAction(actionMap.get("stop_calc")); // NOI18N
        jMenuItem5.setName("jMenuItem5"); // NOI18N
        jMenu1.add(jMenuItem5);

        jMenuItem16.setAction(actionMap.get("view_result")); // NOI18N
        jMenuItem16.setName("jMenuItem16"); // NOI18N
        jMenu1.add(jMenuItem16);

        jSeparator13.setName("jSeparator13"); // NOI18N
        jMenu1.add(jSeparator13);

        jMenuItem4.setAction(actionMap.get("delete_object")); // NOI18N
        jMenuItem4.setName("jMenuItem4"); // NOI18N
        jMenu1.add(jMenuItem4);

        jSeparator3.setName("jSeparator3"); // NOI18N
        jMenu1.add(jSeparator3);

        jMenuItem12.setAction(actionMap.get("link_select")); // NOI18N
        jMenuItem12.setName("jMenuItem12"); // NOI18N
        jMenu1.add(jMenuItem12);

        jMenuItem13.setAction(actionMap.get("link_orient")); // NOI18N
        jMenuItem13.setName("jMenuItem13"); // NOI18N
        jMenu1.add(jMenuItem13);

        jSeparator6.setName("jSeparator6"); // NOI18N
        jMenu1.add(jSeparator6);

        jMenuItem6.setAction(actionMap.get("object_properties")); // NOI18N
        jMenuItem6.setName("jMenuItem6"); // NOI18N
        jMenu1.add(jMenuItem6);

        menuBar.add(jMenu1);

        jMenu2.setText(resourceMap.getString("jMenu2.text")); // NOI18N
        jMenu2.setName("jMenu2"); // NOI18N

        jMenuItem7.setAction(actionMap.get("set_size")); // NOI18N
        jMenuItem7.setName("jMenuItem7"); // NOI18N
        jMenu2.add(jMenuItem7);

        jSeparator10.setName("jSeparator10"); // NOI18N
        jMenu2.add(jSeparator10);

        jMenuItem8.setAction(actionMap.get("move_up")); // NOI18N
        jMenuItem8.setName("jMenuItem8"); // NOI18N
        jMenu2.add(jMenuItem8);

        jMenuItem9.setAction(actionMap.get("move_down")); // NOI18N
        jMenuItem9.setName("jMenuItem9"); // NOI18N
        jMenu2.add(jMenuItem9);

        jMenuItem10.setAction(actionMap.get("move_left")); // NOI18N
        jMenuItem10.setName("jMenuItem10"); // NOI18N
        jMenu2.add(jMenuItem10);

        jMenuItem11.setAction(actionMap.get("move_right")); // NOI18N
        jMenuItem11.setName("jMenuItem11"); // NOI18N
        jMenu2.add(jMenuItem11);

        jSeparator12.setName("jSeparator12"); // NOI18N
        jMenu2.add(jSeparator12);

        jMenuItem17.setAction(actionMap.get("print_table_panel")); // NOI18N
        jMenuItem17.setName("jMenuItem17"); // NOI18N
        jMenu2.add(jMenuItem17);

        jMenuItem14.setAction(actionMap.get("save_image")); // NOI18N
        jMenuItem14.setName("jMenuItem14"); // NOI18N
        jMenu2.add(jMenuItem14);

        menuBar.add(jMenu2);

        helpMenu.setText(resourceMap.getString("helpMenu.text")); // NOI18N
        helpMenu.setName("helpMenu"); // NOI18N

        aboutMenuItem.setAction(actionMap.get("showAboutBox")); // NOI18N
        aboutMenuItem.setName("aboutMenuItem"); // NOI18N
        helpMenu.add(aboutMenuItem);

        menuBar.add(helpMenu);

        statusPanel.setName("statusPanel"); // NOI18N

        statusPanelSeparator.setName("statusPanelSeparator"); // NOI18N

        statusMessageLabel.setName("statusMessageLabel"); // NOI18N

        statusAnimationLabel.setHorizontalAlignment(javax.swing.SwingConstants.LEFT);
        statusAnimationLabel.setName("statusAnimationLabel"); // NOI18N

        progressBar.setName("progressBar"); // NOI18N

        javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(statusPanel);
        statusPanel.setLayout(statusPanelLayout);
        statusPanelLayout.setHorizontalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(statusPanelSeparator, javax.swing.GroupLayout.DEFAULT_SIZE, 695, Short.MAX_VALUE)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addContainerGap()
                .addComponent(statusMessageLabel)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 525, Short.MAX_VALUE)
                .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(statusAnimationLabel)
                .addContainerGap())
        );
        statusPanelLayout.setVerticalGroup(
            statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(statusPanelLayout.createSequentialGroup()
                .addComponent(statusPanelSeparator, javax.swing.GroupLayout.PREFERRED_SIZE, 2, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(statusPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(statusMessageLabel)
                    .addComponent(statusAnimationLabel)
                    .addComponent(progressBar, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addGap(3, 3, 3))
        );

        setComponent(mainPanel);
        setMenuBar(menuBar);
        setStatusBar(statusPanel);
    }// </editor-fold>//GEN-END:initComponents

    public javax.swing.ActionMap actionMap = org.jdesktop.application.Application.getInstance(treepro.TreeProApp.class).getContext().getActionMap(TreeProView.class, this);
    
    // Variables declaration - do not modify//GEN-BEGIN:variables
    public javax.swing.JToggleButton addLinkBtn;
    public javax.swing.JToggleButton addNodeBtn;
    private javax.swing.JButton jButton1;
    private javax.swing.JButton jButton10;
    private javax.swing.JButton jButton11;
    private javax.swing.JButton jButton12;
    private javax.swing.JButton jButton13;
    private javax.swing.JButton jButton14;
    private javax.swing.JButton jButton16;
    private javax.swing.JButton jButton17;
    private javax.swing.JButton jButton18;
    private javax.swing.JButton jButton2;
    private javax.swing.JButton jButton3;
    private javax.swing.JButton jButton4;
    private javax.swing.JButton jButton5;
    private javax.swing.JButton jButton6;
    private javax.swing.JButton jButton7;
    private javax.swing.JButton jButton8;
    private javax.swing.JButton jButton9;
    private javax.swing.JMenu jMenu1;
    private javax.swing.JMenu jMenu2;
    private javax.swing.JMenuItem jMenuItem1;
    private javax.swing.JMenuItem jMenuItem10;
    private javax.swing.JMenuItem jMenuItem11;
    private javax.swing.JMenuItem jMenuItem12;
    private javax.swing.JMenuItem jMenuItem13;
    private javax.swing.JMenuItem jMenuItem14;
    private javax.swing.JMenuItem jMenuItem15;
    private javax.swing.JMenuItem jMenuItem16;
    private javax.swing.JMenuItem jMenuItem17;
    private javax.swing.JMenuItem jMenuItem2;
    private javax.swing.JMenuItem jMenuItem3;
    private javax.swing.JMenuItem jMenuItem4;
    private javax.swing.JMenuItem jMenuItem5;
    private javax.swing.JMenuItem jMenuItem6;
    private javax.swing.JMenuItem jMenuItem7;
    private javax.swing.JMenuItem jMenuItem8;
    private javax.swing.JMenuItem jMenuItem9;
    private javax.swing.JPanel jPanel1;
    private javax.swing.JPanel jPanel2;
    private javax.swing.JPanel jPanel3;
    private javax.swing.JPopupMenu.Separator jSeparator1;
    private javax.swing.JPopupMenu.Separator jSeparator10;
    private javax.swing.JToolBar.Separator jSeparator11;
    private javax.swing.JPopupMenu.Separator jSeparator12;
    private javax.swing.JPopupMenu.Separator jSeparator13;
    private javax.swing.JToolBar.Separator jSeparator14;
    private javax.swing.JPopupMenu.Separator jSeparator2;
    private javax.swing.JPopupMenu.Separator jSeparator3;
    private javax.swing.JToolBar.Separator jSeparator4;
    private javax.swing.JToolBar.Separator jSeparator5;
    private javax.swing.JPopupMenu.Separator jSeparator6;
    private javax.swing.JToolBar.Separator jSeparator7;
    private javax.swing.JToolBar.Separator jSeparator8;
    private javax.swing.JToolBar.Separator jSeparator9;
    private javax.swing.JTabbedPane jTabbedPane1;
    private javax.swing.JToolBar jToolBar1;
    private javax.swing.JToolBar jToolBar2;
    private javax.swing.JToolBar jToolBar3;
    private javax.swing.JLabel labCurrPath;
    private javax.swing.JLabel labPathCnt;
    public javax.swing.JLabel labelTime;
    private javax.swing.JPanel mainPanel;
    private javax.swing.JMenuBar menuBar;
    public javax.swing.JTable nodesTable;
    private javax.swing.JProgressBar progressBar;
    private javax.swing.JLabel statusAnimationLabel;
    private javax.swing.JLabel statusMessageLabel;
    private javax.swing.JPanel statusPanel;
    public javax.swing.JScrollPane tableScrollPane;
    // End of variables declaration//GEN-END:variables

    private final Timer messageTimer;
    private final Timer busyIconTimer;
    private final Icon idleIcon;
    private final Icon[] busyIcons = new Icon[15];
    private int busyIconIndex = 0;
    
    private JDialog aboutBox;
    

    public void addPatch(float curMin, int[] patch) {

        TreeProApp.resultPaths.add(patch);
        labCurrPath.setText(""+curMin);
        labPathCnt.setText(""+TreeProApp.paths.size());
        TreeProApp.resultFrame.refreshResult(TreeProApp.resultPaths.size()-1);
    }

    public void finish() {
        finish("["+new Date()+ "] Расчет завершен.\n",true);
    }

    public void finish(String out, boolean isPatch) {
        finish(out, isPatch, null);
    }
    
    public void finish(String out, boolean isPatch, float[][] metl_arr) {
        refreshTask.alive=false;
        TreeProApp.inProcess = false;
        
        if ((!isPatch)&&(!TreeProApp.paths.isEmpty())) {
            
            // Расчет времени
            int [] m = TreeProApp.paths.get(TreeProApp.paths.size()-1);
            NodeObject no1 = null;
            NodeObject no2 = null;
            LineObject line = null;
            
            double sum = 0.0;
            for (int i = 0; i< m.length-1; i++) {
                no1 = treePanel.findByNumber(m[i]+1);
                no2 = treePanel.findByNumber(m[i+1]+1);
                line = treePanel.findLink(no1, no2);
                sum += line.distance/line.speed + no1.unloadTime + no1.lapTime;
            }
            sum+=no2.unloadTime+ no2.lapTime;
            
            out+="\nВремя в прямом: "+sum;

            sum = 0.0;
            for (int i = 0; i< m.length-1; i++) {
                no1 = treePanel.findByNumber(m[i]+1);
                no2 = treePanel.findByNumber(m[i+1]+1);
                line = treePanel.findLink(no2, no1);
                sum += line.distance/line.speed;
            }
            out+="\nВремя в обратном: "+sum;
        }

        TreeProApp.resultFrame.areaReport.append("\n"+out);
        
        calcBestWork();
        TreeProApp.resultFrame.setVisible(true);
        TreeProApp.main.actionMap.get("start_calc").setEnabled(true);
        TreeProApp.main.actionMap.get("file_new").setEnabled(true);
        TreeProApp.main.actionMap.get("file_open").setEnabled(true);
        
        TreeProApp.main.actionMap.get("stop_calc").setEnabled(false);
        
    }
    
    public void calcBestWork() {
        //TreeProApp.resultFrame.best_work_patch = null;
        TreeProApp.resultFrame.best_work = Double.MAX_VALUE;
        List<int[]> paths_tmp = new ArrayList<int[]>(TreeProApp.paths);
        for (Iterator<int[]> it = paths_tmp.iterator(); it.hasNext();) {
            int[] obj = it.next();
            TreeProApp.resultFrame.calcWork(Arrays.copyOf(obj, obj.length),true);
        }
        
        
		if (TreeProApp.resultFrame.best_work_patch!=null) {
			TreeProApp.resultFrame.best_work = Double.MAX_VALUE;
			TreeProApp.resultFrame.areaReport.append("\n--------------\nЛучшая работа: "+TreeProApp.resultFrame.calcWork(Arrays.copyOf(TreeProApp.resultFrame.best_work_patch, TreeProApp.resultFrame.best_work_patch.length)));
		}
    }

    public void start() {
        refreshTask = new RefreshTask(getApplication());
        taskMonitor.setForegroundTask(refreshTask);
        refreshTask.execute();
    }

    public void linkPatch(List<int[]> patchs) {
        //TreeProApp.paths.clear();
        TreeProApp.paths=patchs;
    }

    public void incProgressBar() {
        //throw new UnsupportedOperationException("Not supported yet.");
    }

    public void error(String str) {
        //refreshTask.alive = false;
        //TreeProApp.inProcess = false;
        TreeProApp.resultFrame.areaError.setText(TreeProApp.resultFrame.areaError.getText()+"\n["
                +new Date()+"] Сбой выполнения с сообщением: "+str);
        /*
        JOptionPane.showMessageDialog(getFrame(), "Сбой выполнения с сообщением: "+
                str+"\nПроцесс вычисления остановлен.", "Фатальная ошибка", 
                JOptionPane.ERROR_MESSAGE);
         * 
         */
    }

    
    
    @Action
    public void start_calc() {
        if (treePanel.getLines().size()<2) {
            JOptionPane.showMessageDialog(getFrame(), "Недостаточно данных для выполнения операции. Добавьте вершины и установите связи.", 
                    "Отменено", JOptionPane.WARNING_MESSAGE);
            return;
        }
            
        if (TreeProApp.runDialog==null)
           TreeProApp.runDialog = new RunDialog(getFrame(), true, this);
        if (TreeProApp.inProcess) {
            if (JOptionPane.showConfirmDialog(getFrame(), 
                    "Процесс вычислений еще не закончен, точно остановить?", "Остановка решения", 
                    JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)==JOptionPane.YES_OPTION) {
                TreeProApp.inProcess = false;
                refreshTask.alive=false;
                // ?????
                if (TreeProApp.calcsdk!=null) {
                    TreeProApp.calcsdk.stop();
                    
                }
                    
            }
            
        } else {
            TreeProApp.runDialog.setVisible(true);
        }
            
        
    }
/*
    @Action
    public void view_node() {
    }

    @Action
    public void view_table() {
    }

    @Action
    public void delete_cell() {
    }

    @Action
    public void cell_prop() {
    }

    @Action
    public void cell_orient() {
    }

    @Action
    public void cell_select() {
    }

    @Action
    public void convert_graph_table() {
    }
*/
    @Action
    public void link_allConvert() {
        if (JOptionPane.showConfirmDialog(getFrame(), "Выполнить преобразование?", 
                "Подтвердите", JOptionPane.YES_NO_OPTION, 
                JOptionPane.QUESTION_MESSAGE)==JOptionPane.YES_OPTION)
            treePanel.link_allConvert();
    }

    public void clearResults() {
        labPathCnt.setText("0");
        labCurrPath.setText("0");
        TreeProApp.resultFrame.clearResults();
        //labelTime.setText("0");
    }

    public void bugPatch(List<Patch> bugPatch, int bugNode, String bugMatrix) {
        TreeProApp.loopPaths.add(new BeanLoop(bugPatch, bugNode, bugMatrix));
        TreeProApp.resultFrame.refreshLoop(TreeProApp.loopPaths.size()-1);
    }

    @Action
    public void stop_calc() {
        if (TreeProApp.inProcess) {
            if (JOptionPane.showConfirmDialog(getFrame(), 
                    "Процесс вычислений еще не закончен, точно остановить?", "Остановка решения", 
                    JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE)==JOptionPane.YES_OPTION) {
                TreeProApp.inProcess = false;
                refreshTask.alive=false;
                // ?????
                if (TreeProApp.calcsdk!=null) {
                    TreeProApp.main.actionMap.get("stop_calc").setEnabled(false);
                    TreeProApp.calcsdk.stop();
                    
                } 
            }
        } else {
            JOptionPane.showMessageDialog(getFrame(), "Расчет не выполняется", "Остановлено", JOptionPane.WARNING_MESSAGE);
        }
        
    }

    @Action
    public void print_table_panel() {
        // Печатать только видимую область с боковыми названиями строк (формат A4 - Альбом)
        treePanel.updateTable(true);
        PrintUtilities.printComponent(tableScrollPane);
        treePanel.updateTable();
    }

    public boolean isProcess() {
        return TreeProApp.inProcess;
    }
    
}
